home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
gnu
/
oleo-1_4.lha
/
oleo-1.4
/
input.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-14
|
10KB
|
428 lines
/* Copyright (C) 1993 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this software; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "global.h"
#include "input.h"
#include "cmd.h"
#include "window.h"
#include "io-abstract.h"
/* In the functions below, we only ever deal with one input_view at a
* time. By convention, call a pointer to it THIS_IV and use these
* macros:
*/
#define Redraw_needed (this_iv->redraw_needed)
#define Prompt_metric (this_iv->prompt_metric)
#define Input_metric (this_iv->input_metric)
#define Keymap_prompt (this_iv->keymap_prompt)
#define Expanded_keymap_prompt (this_iv->expanded_keymap_prompt)
#define Prompt_wid (this_iv->prompt_wid)
#define Must_fix_input (this_iv->must_fix_input)
#define Input_area (this_iv->input_area)
#define Prompt (this_iv->prompt)
#define Visibility_begin (this_iv->visibility_begin)
#define Visibility_end (this_iv->visibility_end)
#define Current_info (this_iv->current_info)
#define Info_pos (this_iv->info_pos)
#define Info_redraw_needed (this_iv->info_redraw_needed)
#define Vis_wid (this_iv->vis_wid)
#define Input_cursor (this_iv->input_cursor)
#define Max(A,B) ((A) < (B) ? (B) : (A))
#define Min(A,B) ((A) > (B) ? (B) : (A))
/* Decide if a keymap prompt should be displayed. If so,
* return the prompt, else 0.
*/
#ifdef __STDC__
static char *
desired_keymap_prompt (struct input_view * this_iv)
#else
static char *
desired_keymap_prompt (this_iv)
struct input_view * this_iv;
#endif
{
int map = cur_keymap;
if (the_cmd_frame->cmd && (the_cmd_arg.style == &keyseq_style))
map = the_cmd_arg.val.key.cmd.code;
return ((map >= 0) ? map_prompts[map] : 0);
}
/* In WID columns, find the first char in STR that can
* be displayed while still leaving POS visible. METRIC
* converts str->cols.
*/
#ifdef __STDC__
static int
find_vis_begin (int * wid_used, int wid,
char * str, int pos, text_measure metric)
#else
static int
find_vis_begin (wid_used, wid, str, pos, metric)
int * wid_used;
int wid;
char * str;
int pos;
text_measure metric;
#endif
{
int used; /* How many cols allocated? */
if (str[pos])
used = metric (&str[pos], 1);
else
/* POS could be just after the end of STR, in which case pretend
* that the character there is a SPC.
*/
used = metric (" ", 1);
while (pos && (used < wid))
{
int next;
next = metric (&str[pos - 1], 1);
if (used + next > wid)
break;
else
{
--pos;
used += next;
}
}
if (wid_used)
*wid_used = used;
return pos;
}
/* Find the last visible character... -1 if none are vis. */
#ifdef __STDC__
static int
find_vis_end (int * wid_used, int wid, char * str, int start, text_measure
metric)
#else
static int
find_vis_end (wid_used, wid, str, start, metric)
int * wid_used;
int wid;
char * str;
int start;
text_measure metric;
#endif
{
int used = metric (&str[start], 1); /* How many cols allocated? */
int pos = start;
int max = strlen (str) - 1;
while ((pos < max) && (used < wid))
{
int next;
next = metric (&str[pos + 1], 1);
if (used + next > wid)
break;
else
{
++pos;
used += next;
}
}
if (wid_used)
*wid_used = used;
return pos;
}
#ifdef __STDC__
static void
set_vis_wid (struct input_view * this_iv)
#else
static void
set_vis_wid (this_iv)
struct input_view * this_iv;
#endif
{
Vis_wid = (Input_metric (Input_area->buf + Visibility_begin,
Visibility_end - Visibility_begin)
+ ((Input_cursor > Visibility_end)
? Input_metric (" ", 1)
: 0));
}
/* This recomputes the input area parameters of an input_view, attempting to
* center the cursor.
*/
#ifdef __STDC__
static void
iv_reset_input (struct input_view * this_iv)
#else
void
static iv_reset_input (this_iv)
struct input_view * this_iv;
#endif
{
char * km = desired_keymap_prompt (this_iv);
if (km && (km == Keymap_prompt))
return;
Redraw_needed = FULL_REDRAW;
Keymap_prompt = km;
if (km)
{
/* A keymap prompt should be displayed. */
Expanded_keymap_prompt = expand_prompt (Keymap_prompt);
Prompt_wid = Prompt_metric (Expanded_keymap_prompt,
strlen(Expanded_keymap_prompt));
Must_fix_input = 1;
Visibility_begin = Visibility_end = 0;
Input_area = 0;
Vis_wid = Input_metric (" ", 1);
Prompt = 0;
Input_cursor = 0;
}
else
{
if (Expanded_keymap_prompt)
{
ck_free (Expanded_keymap_prompt);
Expanded_keymap_prompt = 0;
}
if (!the_cmd_frame->cmd || the_cmd_arg.is_set || !the_cmd_arg.do_prompt)
{
Prompt_wid = 0;
Must_fix_input = 0;
Input_area = 0;
Vis_wid = 0;
Prompt = 0;
Visibility_begin = Visibility_end = 0;
Input_cursor = 0;
}
else
{
Prompt_wid = Prompt_metric (the_cmd_arg.expanded_prompt,
strlen (the_cmd_arg.expanded_prompt));
Must_fix_input = 0;
Input_area = &the_cmd_arg.text;
Prompt = the_cmd_arg.expanded_prompt;
if ((scr_cols - Prompt_wid) < Input_metric ("M", 1))
Prompt += find_vis_begin (&Prompt_wid,
scr_cols - Input_metric("M", 1),
Prompt, strlen(Prompt) - 1,
Prompt_metric);
{
int wid_avail = scr_cols - Prompt_wid;
Visibility_begin =
find_vis_begin (0, wid_avail / 2, Input_area->buf,
the_cmd_arg.cursor, Input_metric);
Visibility_end =
find_vis_end (0, wid_avail,
Input_area->buf, Visibility_begin,
Input_metric);
}
Input_cursor = the_cmd_arg.cursor;
set_vis_wid (this_iv);
}
}
}
/* This is called strategicly from the command loop and whenever
* the input area is changed by beginning a complex command.
* It may do nothing, though if the input area appeas to have changed
* it will recompute its appearence.
*
* now it also updates the info_fields of the input view.
*/
#ifdef __STDC__
void
iv_fix_input (struct input_view * this_iv)
#else
void
iv_fix_input (this_iv)
struct input_view * this_iv;
#endif
{
char * km_prompt = desired_keymap_prompt (this_iv);
if (Keymap_prompt && (Keymap_prompt == km_prompt))
Must_fix_input = 1; /* Do nothing, keymap prompt has precedence */
else if (Must_fix_input
|| (Keymap_prompt != km_prompt)
|| ((the_cmd_frame->cmd
&& (the_cmd_arg.do_prompt && !the_cmd_arg.is_set))
? ((Input_area != &the_cmd_arg.text)
|| (Prompt != the_cmd_arg.expanded_prompt)
|| (Input_cursor != the_cmd_arg.cursor))
: (Input_area || Prompt_wid)))
iv_reset_input (this_iv);
if (the_cmd_frame->cmd
&& ((the_cmd_arg.prompt_info != Current_info)
|| (the_cmd_arg.info_line != Info_pos)))
{
Current_info = the_cmd_arg.prompt_info;
Info_pos = the_cmd_arg.info_line;
Info_redraw_needed = 1;
}
else if (Current_info
&& (!the_cmd_frame->cmd || !the_cmd_arg.prompt_info))
{
Current_info = 0;
io_repaint ();
}
}
/* Incremental updates:
* For simple edits it is not necessary to redraw the entire line.
* These schedule incremental updating.
*/
#ifdef __STDC__
void
iv_move_cursor (struct input_view * this_iv)
#else
void
iv_move_cursor (this_iv)
struct input_view * this_iv;
#endif
{
if ( Must_fix_input
|| (Visibility_begin > the_cmd_arg.cursor)
|| ( ((Visibility_end + 1) < the_cmd_arg.cursor)
|| (((Visibility_end + 1) == the_cmd_arg.cursor)
&& ((Vis_wid + Prompt_wid) < scr_cols))))
Must_fix_input = 1;
else if (Redraw_needed != FULL_REDRAW)
{
if ( (Redraw_needed == NO_REDRAW)
|| ((Redraw_needed > Input_cursor)
&& (Redraw_needed > the_cmd_arg.cursor)))
{
Input_cursor = the_cmd_arg.cursor;
set_vis_wid (this_iv);
}
else
{
Redraw_needed = Min (Input_cursor, the_cmd_arg.cursor);
set_vis_wid (this_iv);
}
}
}
#ifdef __STDC__
void
iv_erase (struct input_view * this_iv, int len)
#else
void
iv_erase (this_iv, len)
struct input_view * this_iv;
int len;
#endif
{
if (Must_fix_input
|| (the_cmd_arg.cursor <= Visibility_begin))
{
Must_fix_input = 1;
return;
}
else if (Redraw_needed != FULL_REDRAW)
{
if ((Redraw_needed == NO_REDRAW) || (Redraw_needed > the_cmd_arg.cursor))
{
Redraw_needed = the_cmd_arg.cursor;
Visibility_end = find_vis_end (0, scr_cols - Prompt_wid,
Input_area->buf, Visibility_begin,
Input_metric);
Input_cursor = the_cmd_arg.cursor;
}
else
Redraw_needed = the_cmd_arg.cursor;
set_vis_wid (this_iv);
}
}
#ifdef __STDC__
void
iv_insert (struct input_view * this_iv, int len)
#else
void
iv_insert (this_iv, len)
struct input_view * this_iv;
int len;
#endif
{
if (!Must_fix_input)
{
int new_end;
int cursor_past_end = (Input_cursor + len == strlen (Input_area->buf));
new_end = find_vis_end (0, scr_cols - Prompt_wid,
Input_area->buf, Visibility_begin,
Input_metric);
if ((new_end + cursor_past_end) < (Input_cursor + len))
Must_fix_input = 1;
else
{
if ( (Redraw_needed != FULL_REDRAW)
&& ((Redraw_needed == NO_REDRAW) || (Redraw_needed > Input_cursor)))
Redraw_needed = Input_cursor;
Input_cursor += len;
Visibility_end = new_end;
set_vis_wid (this_iv);
}
}
}
#ifdef __STDC__
void
iv_over (struct input_view * this_iv, int len)
#else
void
iv_over (this_iv, len)
struct input_view * this_iv;
int len;
#endif
{
iv_insert (this_iv, len);
}